<?php
/**
 * This class represents an Activity in the OpenSocial API.
 * 
 * Using activities are very simple and to create an OSActivity is as simple as:
 * <code>
 * $this->activity = new OSActivity('update_musics');
 * </code>
 * You can create and send an OSActivity inside the Action like this:
 * <code>
 * //Action
 * $this->mediaItem = new OSActivityMediaItem('logo');
 * $this->mediaItem->setImageItem();
 * $this->mediaItem->setURL('http://www.palcoprincipal.com/images/logo_opensocial_pp.png');
 * 
 * $this->activity->addMediaItem($this->mediaItem);
 * $this->activity->setTitle('New Music Added!');
 * $this->activity->createActivity(true);
 * </code>
 * Or if you like to setup the OSActivity object in the Action an execute it in the View you can do like this:
 * <code>
 * //Action
 * $this->mediaItem = new OSActivityMediaItem('logo');
 * $this->mediaItem->setImageItem();
 * $this->mediaItem->setURL('http://www.palcoprincipal.com/images/logo_opensocial_pp.png');
 * 
 * $this->activity->addMediaItem($this->mediaItem);
 * $this->activity->setPattern('title','O utilizador %s actualizou a musica %s às %s!');
 * //View
 * function <?php $activity->getJSFunction->getName()?>() {  
 *     <?php $activity->setTitle(sprintf($activity->getPattern('title'),'eu','lah lah','aa')); 
 *           $activity->createActivity(false);
 *           echo $activity;
 * 
 *     ?>
 *   };
 * </code> 
 * 
 * @package    opensocial
 * @subpackage activity
 * @author     Daniel Botelho <botelho.daniel@gmail.com>
 */
class OSActivity
{ 
  private static $DEFAULT_CLASS = 'opensocial.Activity';
  private static $GET_FIELD_PATTERN = '%s.getField(%s)';
  
  // nome da variável da actividade
  private $activity_var;
  
  // nome da variável dos parametros da actividade
  private $activityParams_var;
  private $activityParams = array();
  private $mediaItems_var;
  private /*OSActivityMediaItem[]*/ $mediaItems = array();
  
  /**
   * This is the JavaScript functio used to create this activity
   */  
  private $create_func;

  // este é um array de padrões que podem ser usados
  // exemplo: $pattern['title'] = 'O utilizador %s actualizou a musica %s!';
  private $pattern = array();

  // Função opcional que é chamada em caso de erro.
  private $opt_callback;

  // A prioridade desta actividade
  private $priority;
 
  /**
  * This constructor creates an instance of OSActivity.
  * @param string The name used for this activity.
  */
  function __construct($activity_var)
  {
    $this->activity_var = $activity_var;
    $this->activityParams_var = $activity_var.'_params';
    $this->mediaItems_var = $activity_var.'_mediaItems';
    $this->setErrorCallbackFunction(new JSFunctionErrorCallback($this));
    $this->setHighPriority();
    $this->create_func= new JSFunction($activity_var.'_function',null,null);
  }

  public function setHighPriority(){ $this->priority = OSActivityPriority::HIGH; }
  public function setLowPriority(){ $this->priority = OSActivityPriority::LOW; }
  public function getPriority(){ return $this->priority; }
  
  public function setErrorCallbackFunction(JSFunction $opt_callback)
  {
    $this->opt_callback = $opt_callback;
  }

  public function getErrorCallbackFunction()
  {
    return $this->opt_callback;
  }
  
  /**
   * This function creates an Activity
   * @param boolean If true, there will be injected the JSFunction in the response; else it will just generate the JSFunction but will not inject in the response.
   * @param boolean $noCallback If it should inclue the callback function
   * 
   */
  public function createActivity($inject =true,$noCallback=false)
  {
    if($noCallback) $this->opt_callback = false;
      
    if(!$this->create_func->getContent()){
      $this->create_func->setContent($this->__toString());
    }
  	if($inject){
  		$ret = JSFunction::addJSTags($this->create_func);
  		echo $ret;
  	}
  }
  
  /**
   * This method returns the JSFunction used to create this activity
   * @return JSFunction The JSFunction used to create this activity
   */
  public function getJSFunction(){ return $this->create_func; }
  
  public function __toString(){
  	$params_var = $this->getActivityParamsVarName();
    $params = $this->getActivityParams();
    $html = '';
    $mediaItems = $this->getActivityMediaItems();
    if(count($mediaItems) > 0){
      $mediaItems_var = $this->getActivityMediaItemsVarName();
      $html .= 'var '. $mediaItems_var." = new Array();\n";

      for( $i=0; $i < count($mediaItems); $i++)
        $html .= $mediaItems_var."[$i] = opensocial.newActivityMediaItem(".$mediaItems[$i]->getType().",'".$mediaItems[$i]->getURL()."');\n";
    }

    $html .= 'var '. $params_var." = {};\n";
    foreach($params as $key => $value) {
      $html .= $params_var.'['.$key .']='. $value . ";\n";
    }

    $activity_var = $this->getActivityVarName();
    $html .= "var $activity_var = opensocial.newActivity($params_var);\n";
    $activity_priority = $this->getPriority();
    $html .= "opensocial.requestCreateActivity($activity_var, $activity_priority";

    if($this->getErrorCallbackFunction())
    {
      $callback = $this->getErrorCallbackFunction();
      $html .= ',';
      if($callback->getName())
        $html .= $callback->getName();
      else{
        $html .= JSFunction::renderFunction($callback);
      }
    }

    $html .= ");\n";
    return $html;
  }
  
  public function addMediaItem(OSActivityMediaItem $mediaItem)
  {
    if(count($this->mediaItems) == 0)
      $this->activityParams[OSActivityField::MEDIA_ITEMS] = $this->mediaItems_var;
    $this->mediaItems[] = $mediaItem;
  }

  /**
  * This method allows to set the pattern for a variable
  * @param string $key The key value
  * @param string $value The value
  */
  public function setPattern($key,$value)
  {
    $this->pattern[$key] = $value;
  }

  /**
   * Get's the Value of a specific Key
   * @param string The key
   * @return string The value for this Key
   */
  public function getPattern($key)
  {
    return $this->pattern[$key];
  }

  public function getActivityVarName(){ return $this->activity_var; }
  public function getActivityParamsVarName(){ return $this->activityParams_var; }
  public function getActivityParams(){ return $this->activityParams; }
  public function getActivityMediaItemsVarName(){ return $this->mediaItems_var; }
  public function getActivityMediaItems(){ return $this->mediaItems; }

  /**
   * Enter description here...
   *
   * @param String $title The title of this activity
   * @param boolean $js_param If the title is a javascript variable
   */
  public function setTitle($title,$js_param=false)
  { 
    $title_val = ($js_param)? $title : "'$title'";
    $this->activityParams[OSActivityField::TITLE] = $title_val;
  }
  public function setTitleID($titleID)
  { 
    $this->activityParams[OSActivityField::TITLE_ID] = "'$titleID'";
  }
  public function getField($field,$appendable){
    $val = sprintf(OSActivity::GET_FIELD_PATTERN,$this->getActivityVarName(),$field);// . ($appendable)? '' : ";\n";
    $val .= ($appendable)? '' : ";\n";
    return $val;
  }
}
